package com.hclc.yxb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hclc.config.context.AppContext;
import com.hclc.config.util.AssertUtil;
import com.hclc.entity.dvo.AdministratorDvo;
import com.hclc.entity.model.SysUserModel;
import com.hclc.entity.model.contans.ApiConst;
import com.hclc.entity.model.enums.AdminStatusEnum;
import com.hclc.util.password.BCryptPasswordEncoder;
import com.hclc.yxb.ao.AddAdministratorAo;
import com.hclc.yxb.ao.ModAdministratorAo;
import com.hclc.yxb.dto.AdministratorDto;
import com.hclc.yxb.dto.AuthorityRoleDto;
import com.hclc.yxb.mapper.SysRoleMapper;
import com.hclc.yxb.mapper.SysUserMapper;
import com.hclc.yxb.mapper.SysUserRoleMapper;
import com.hclc.yxb.model.SysRoleModel;
import com.hclc.yxb.model.SysUserRoleModel;
import com.hclc.yxb.service.AdministratorManagementService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName PwlAdministratorManagementServiceImpl
 * @Author: yurj
 * @Mail：1638234804@qq.com
 * @Date: Create in 20:12 2020/8/22
 * @version: 1.0
 */
@Service
@Slf4j
public class AdministratorManagementServiceImpl implements AdministratorManagementService {
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    /**
     * 查询管理员列表
     *
     * @param page
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.hclc.pwl.dto.AdministratorDvo>
     * @author yurj
     * @mail 1638234804@qq.com
     * @version 1.0
     * @date 2020/8/22 21:09
     */
    @Override
    public IPage<AdministratorDto> selectAdministrator(Page<AdministratorDvo> page) {
        SysUserModel sysUserModel = AppContext.getCurrentUser(SysUserModel.class);
        IPage<AdministratorDvo> dataPage = sysUserMapper.selectUserList(page, sysUserModel.getId());
        List<AdministratorDto> dtoList = new ArrayList<>();
        dataPage.getRecords().stream().forEach(s -> {
            AdministratorDto dto = new AdministratorDto();
            try {
                BeanUtils.copyProperties(s, dto);
            } catch (BeansException e) {
                log.error("查询管理员列表赋值异常,source:{},target:{}", s, dto, e);
            }
            dtoList.add(dto);
        });
        IPage<AdministratorDto> resultPage = new Page<>(dataPage.getCurrent(), dataPage.getSize(), dataPage.getTotal());
        return resultPage.setRecords(dtoList);
    }

    /**
     * 查询权限角色列表
     *
     * @param
     * @return java.util.List<com.hclc.pwl.dto.AuthorityRoleDto>
     * @author yurj
     * @mail 1638234804@qq.com
     * @version 1.0
     * @date 2020/8/22 21:53
     */
    @Override
    public List<AuthorityRoleDto> selectAuthorityRole() {
        // 超级管理员
        SysUserModel sysUserModel = sysUserMapper.selectOne(new QueryWrapper<SysUserModel>()
                .lambda()
                .eq(SysUserModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserModel::getAdminStatus, AdminStatusEnum.YES)
        );
        // 超级管理员角色权限
        SysUserRoleModel sysUserRoleModel = sysUserRoleMapper.selectOne(new QueryWrapper<SysUserRoleModel>()
                .lambda()
                .eq(SysUserRoleModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserRoleModel::getUserId, sysUserModel.getId())
        );
        List<SysRoleModel> sysRoleModels = sysRoleMapper.selectList(new QueryWrapper<SysRoleModel>()
                .lambda()
                .eq(SysRoleModel::getEnable, ApiConst.ENABLE_TRUE)
                // 排除超级管理员角色
                .ne(SysRoleModel::getId, sysUserRoleModel.getRoleId())
        );
        List<AuthorityRoleDto> dtoList = new ArrayList<>();
        sysRoleModels.stream().forEach(s -> {
            AuthorityRoleDto dto = new AuthorityRoleDto();
            dto.setRoleId(s.getId());
            dto.setRoleName(s.getRoleName());
            dto.setRoleDesc(s.getRoleDesc());
            dtoList.add(dto);
        });
        return dtoList;
    }

    /**
     * 添加管理员
     *
     * @param ao
     * @return boolean
     * @author yurj
     * @mail 1638234804@qq.com
     * @version 1.0
     * @date 2020/8/22 20:12
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertAdministrator(AddAdministratorAo ao) {
        Integer roleCount = sysRoleMapper.selectCount(new QueryWrapper<SysRoleModel>()
                .lambda()
                .eq(SysRoleModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysRoleModel::getId, ao.getRoleId())
        );
        AssertUtil.isTrue(roleCount > 0, () -> "无效的角色信息");
        Integer userNameCount = sysUserMapper.selectCount(new QueryWrapper<SysUserModel>()
                .lambda()
                .eq(SysUserModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserModel::getUserName, ao.getUserName())
        );
        AssertUtil.isTrue(userNameCount < 1, () -> "登录名已存在");
        // 加密策略
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        SysUserModel sysUserModel = new SysUserModel();
        sysUserModel.setUserName(ao.getUserName());
        sysUserModel.setUserPass(passwordEncoder.encode(ao.getUserPass()));
        sysUserModel.setNick(ao.getNick());
        sysUserModel.setUserLogo(ao.getUserLogo());
        int sysUserInsert = sysUserMapper.insert(sysUserModel);
        AssertUtil.isTrue(sysUserInsert > 0, () -> "添加管理员失败");
        SysUserRoleModel sysUserRoleModel = new SysUserRoleModel();
        sysUserRoleModel.setUserId(sysUserModel.getId());
        sysUserRoleModel.setRoleId(ao.getRoleId());
        int sysRoleInsert = sysUserRoleMapper.insert(sysUserRoleModel);
        AssertUtil.isTrue(sysRoleInsert > 0, () -> "添加管理员角色失败");
        return true;
    }

    /**
     * 删除管理员
     *
     * @param userId
     * @return boolean
     * @author yurj
     * @mail 1638234804@qq.com
     * @version 1.0
     * @date 2020/8/22 20:29
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAdministrator(String userId) {
        sysUserRoleMapper.update(new SysUserRoleModel(), new UpdateWrapper<SysUserRoleModel>()
                .lambda()
                .eq(SysUserRoleModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserRoleModel::getUserId, userId)
                .set(SysUserRoleModel::getEnable, ApiConst.ENABLE_FALSE)
        );
        int userUpdate = sysUserMapper.update(new SysUserModel(), new UpdateWrapper<SysUserModel>()
                .lambda()
                .eq(SysUserModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserModel::getId, userId)
                .set(SysUserModel::getEnable, ApiConst.ENABLE_FALSE)
        );
        AssertUtil.isTrue(userUpdate > 0, () -> "删除管理员失败");
        return true;
    }

    /**
     * 修改管理员
     *
     * @param ao
     * @return boolean
     * @author yurj
     * @mail 1638234804@qq.com
     * @version 1.0
     * @date 2020/8/22 20:37
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAdministrator(ModAdministratorAo ao) {
        SysUserModel sysUserModel = sysUserMapper.selectOne(new QueryWrapper<SysUserModel>()
                .lambda()
                .eq(SysUserModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserModel::getId, ao.getUserId())
        );
        AssertUtil.notNull(sysUserModel, () -> "该账户不存在");
        int roleUpdate = sysUserRoleMapper.update(new SysUserRoleModel(), new UpdateWrapper<SysUserRoleModel>()
                .lambda()
                .eq(SysUserRoleModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserRoleModel::getUserId, ao.getUserId())
                .set(SysUserRoleModel::getRoleId, ao.getRoleId())
        );
        AssertUtil.isTrue(roleUpdate > 0, () -> "更新管理员权限失败");
        if (!Objects.equals(sysUserModel.getUserName(), ao.getUserName())) {
            Integer userNameCount = sysUserMapper.selectCount(new QueryWrapper<SysUserModel>()
                    .lambda()
                    .eq(SysUserModel::getEnable, ApiConst.ENABLE_TRUE)
                    .eq(SysUserModel::getUserName, ao.getUserName())
            );
            AssertUtil.isTrue(userNameCount < 1, () -> "登录名已存在");
        }

        if (StringUtils.isNotBlank(ao.getUserPass())) {
            // 加密策略
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            sysUserModel.setUserPass(passwordEncoder.encode(ao.getUserPass()));
        }
        sysUserModel.setUserName(ao.getUserName());
        sysUserModel.setNick(ao.getNick());
        sysUserModel.setUserLogo(ao.getUserLogo());
        int sysUserUpdate = sysUserMapper.update(sysUserModel, new UpdateWrapper<SysUserModel>()
                .lambda()
                .eq(SysUserModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserModel::getId, ao.getUserId())
        );
        AssertUtil.isTrue(sysUserUpdate > 0, () -> "修改管理员失败");
        return true;
    }

    /**
     * 管理员修改自身密码
     *
     * @param password
     * @return boolean
     * @author yurj
     * @version 1.0
     * @date 2020/11/16 16:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCurrentAdministratorPass(String password) {
        String currentUserId = AppContext.getCurrentUserId();
        // 加密策略
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encodePass = passwordEncoder.encode(password);
        int sysUserUpdate = sysUserMapper.update(new SysUserModel(), new UpdateWrapper<SysUserModel>()
                .lambda()
                .eq(SysUserModel::getEnable, ApiConst.ENABLE_TRUE)
                .eq(SysUserModel::getId, currentUserId)
                .set(SysUserModel::getUserPass, encodePass)
        );
        AssertUtil.isTrue(sysUserUpdate > 0, () -> "修改管理员密码失败");
        return true;
    }

}

